/**
 * @file bsp_dma.c
 * @brief DMA封装驱动
 * @warning 该驱动未完成，待完善
 * @author wangh (wanghuan3037@fiberhome.com)
 * @version 1.0
 * @date 2020-10-22
 * @copyright Copyright (c) 2020  烽火通信
 ***************************************************************
 * @par 修改日志:
 * <table>
 * <tr><th>Date       <th>Version  <th>Author  <th>Description
 * <tr><td>2020-10-22 <td>1.0      <td>wangh   <td>内容
 * </table>
 */ 
#include "bsp_dma.h"
#include <stdbool.h>

static bool dma1_clk_enable = false;
static bool dma2_clk_enable = false;


/**
 * @brief DMA的各通道配置 \n
 * @todo: 这里的传输形式是固定的,这点要根据不同的情况来修改 \n
 * 从存储器->外设模式/8位数据宽度/存储器增量模式
 * @param[in]  DMA_CHx      DMA通道CHx
 * @param[in]  cpar         外设地址
 * @param[in]  cmar         存储器地址
 * @param[in]  cndtr        数据传输量
 */
void DMA_Config( DMA_Channel_TypeDef* DMA_CHx, u32 cpar, u32 cmar, u16 cndtr)
{
    if( ( DMA_CHx < DMA2_Channel1 ) && ( dma1_clk_enable == false ) )
    {
        RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);  /* 使能DMA钟源 */
        dma1_clk_enable = true;
    }
    else if( dma2_clk_enable == false )
    {
        RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2, ENABLE);  /* 使能DMA钟源 */
        dma2_clk_enable = true;
    }

    DMA_InitTypeDef DMA_InitStructure;

    DMA_DeInit( DMA_CHx );    /* 将DMA的通道寄存器重设为缺省值 */
    DMA_InitStructure.DMA_PeripheralBaseAddr = cpar;    /* DMA外设基地址 */
    DMA_InitStructure.DMA_MemoryBaseAddr = cmar;        /* DMA内存基地址 */
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;  /* 数据传输方向，从内存读取发送到外设 */
    DMA_InitStructure.DMA_BufferSize = cndtr;           /* DMA通道的DMA缓存的大小 */
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;    /* 外设地址寄存器不变 */
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; /* 内存地址寄存器递增 */
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_MemoryDataSize_Byte; /* 外设数据宽度8位 */
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;     /* 内存数据宽度8位 */
    DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;       /* 工作在正常模式 */
    DMA_InitStructure.DMA_Priority = DMA_Priority_High; /* DMA通道x拥有中优先级 */
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;        /* DMA通道x没有设置为内存到内存传输 */
    DMA_Init(DMA_CHx, &DMA_InitStructure);
}

/**
 * @brief 开启一次DMA传输
 * @param[in]  DMA_CHx      DMA通道CHx
 */
void DMA_Enable( DMA_Channel_TypeDef *DMA_CHx )
{
    DMA_Cmd( DMA_CHx, DISABLE );
    TIM3->ARR = 2;  /* 由于最后一项是0，所以在最后的时刻ARR会被清零，导致下一次启动无效。*/
    DMA_SetCurrDataCounter(DMA_CHx, DMA1_MEM_LEN);
    DMA_Cmd( DMA_CHx, ENABLE  );
    TIM_Cmd(TIM3, ENABLE ); /* 使能TIM3 */
    TIM3->EGR = 0x00000001; /* 由于最后一次ARR值为0，这是为了停止定时器对io口的操作，但是不要忽略了一点：CNT并没有停止计数，而且是不会再停下来，如果没有手动操作的话，所以需要在每次dma使能时加上一句，将EGR里的UG位置1，清零计数器 */
}


/*********** (C) COPYRIGHT 2020 FiberHome *****END OF FILE****/
